package reese.think_in_java.java_21_thread;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * ***********************************************************
 *
 * @类名 : reese.think_in_java.java_21_thread.类名
 * @DESCRIPTION : 这家伙太懒啥都没写
 * @AUTHOR :  一个风情万种的男子
 * @DATE : 2016/6/4
 * ***********************************************************
 */

class Count{
    private int count = 0;
    private Random rand = new Random(47);

    //Remove the synchronized keyword to see counting fail:
    public synchronized int increment(){
        int temp = count ;
        if(rand.nextBoolean()) ; //Yield half the time
          Thread.yield();
        return (count = ++temp);

    }

    public synchronized  int value() {
        return  count ;
    }
}

class  Entrance implements  Runnable {

    private static  Count count = new Count();

    private  static List<Entrance> entrances = new ArrayList<Entrance>();


    private  int number = 0;

    //Doesn't need synchronization to read:

    private  final  int id ;
    private static  volatile  boolean canceled = false ;

    // Atomic operation on a volatile field:

    public static  void  cancel() {
        canceled = true ;
    }

    public Entrance(int id) {
        this.id = id;
        // Keep this task in  a list . also prevents garbage collection of dead tasks :
        entrances.add(this);
    }

    @Override
    public void run() {
        while (!canceled){
            synchronized (this){
                ++number;
            }
        }
        System.out.println(this + " Total:" + count.increment() );
        try {
            TimeUnit.MILLISECONDS.sleep(100);
        } catch (InterruptedException e) {
            System.out.println("sleep interrupted");
        }
        System.out.println("stopping " + this);
    }

    public synchronized  int getValue(){
        return number ;
    }

    @Override
    public String toString() {
        return "Entrance{}" + id + ": "+getValue();
    }

    public static int getTotalCount(){
        return count.value();
    }

    public static int sumEntrances(){
        int sum = 0 ;
        for (Entrance entrance : entrances){
            sum +=entrance.getValue();
        }
        return  sum ;

    }
}


public class OrnamentalGarden {

    public static void main(String[] args) throws InterruptedException {
        ExecutorService exec = Executors.newCachedThreadPool();
        for(int i=0;i<5;i++){
            exec.execute(new Entrance(i));
        }
        //Run for a while, then stop and collect the data:
        TimeUnit.SECONDS.sleep(3);
        Entrance.cancel();
        exec.shutdown();
        if(!exec.awaitTermination(250,TimeUnit.MILLISECONDS)){
            System.out.println("some task were not terminated");
        }
        System.out.println("total: " + Entrance.getTotalCount());
        System.out.println("Sum of Entrances: " + Entrance.sumEntrances());

    }
}
